package com.hohai.river.utils;

import com.alibaba.fastjson.JSONObject;
import com.pig4cloud.pig.admin.api.feign.RemoteFileService;
import feign.Response;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Component
public class IndexCalculator {

	@Resource
	private RemoteFileService remoteFileService;

	public List<double[]> getIndexValue(String indexName, String... arrayName) {
		Response response = remoteFileService.file(JsonUtils.BUCKET, JsonUtils.FILE_NAME);
		JSONObject jsonObject = JsonUtils.getJsonObjectFromResponse(response).getJSONObject(indexName);
		List<double[]> list = new ArrayList<>();
		for (String name : arrayName) {
			double[] array = jsonObject.getJSONArray(name).stream().mapToDouble(item -> Double.valueOf(item.toString()))
					.toArray();
			list.add(array);
		}
		return list;
	}

	/**
	 * 计算指标评分 防洪
	 * @param rda, rd,river_type
	 * @return score
	 */
	public double fanghongindex_calculator(Double rda, Double rd, Integer river_type) {
		if (rd == 0) {
			return 0;
		}
		List<double[]> indexValue = getIndexValue("fanghongIndex", "scoreIntervals", String.valueOf(river_type));
		double[] scoreIntervals = indexValue.get(0);
		double[] gradeTable = indexValue.get(1);
		double fanghong_rate = rda / rd * 100.0;
		return calculateScore(fanghong_rate, scoreIntervals, gradeTable);
	}

	public double yuanshuiindex_calculator(Integer ad, Integer at, Integer river_type) {
		if (at == 0) {
			return 0;
		}
		List<double[]> indexValue = getIndexValue("yuanshuiIndex", "scoreIntervals", String.valueOf(river_type));
		double[] scoreIntervals = indexValue.get(0);
		double[] gradeTable = indexValue.get(1);
		double yuanshui_rate = ad.doubleValue() / at * 100.0;
		return calculateScore(yuanshui_rate, scoreIntervals, gradeTable);
	}

	public double hangyunindex_calculator(Integer nn, Integer nw, Integer np, Integer river_type) {
		double score = 0;
		List<double[]> indexValue = getIndexValue("hangyunIndex", "scoreIntervals", String.valueOf(river_type));
		double[] scoreIntervals = indexValue.get(0);
		double[] gradeTable = indexValue.get(1);
		double hangyun_rate = nn.doubleValue() / 365 * 100.0;
		score = calculateScore(hangyun_rate, scoreIntervals, gradeTable) - nw - np;
		if (score < 0) {
			score = 0;
		}
		return score;
	}

	public double anpoindex_calculator(Double sar, Double shr, Integer smr, Integer str, Integer river_type) {
		double score = 0;
		double score_1 = 0;
		double score_2 = 0;
		double score_3 = 0;
		double score_4 = 0;

		String[] names = { "scoreIntervals_1", "scoreIntervals_2", String.valueOf(river_type) };
		List<double[]> indexValue = getIndexValue("anpoIndex", names);

		double[] scoreIntervals_1 = indexValue.get(0);
		double[] socreIntervals_2 = indexValue.get(1);
		double[] gradeTable = indexValue.get(2);

		double tartan = Math.toDegrees(Math.atan(shr / sar));
		score_1 = calculateScore_1(tartan, scoreIntervals_1, gradeTable);
		score_2 = calculateScore_1(shr, socreIntervals_2, gradeTable);
		score_3 = gradeTable[smr]; // smr为0、1、2、3，1为最好。
		score_4 = gradeTable[str]; // str为0、1、2、3，1为最好。
		score = (score_1 + score_2 + score_3 + score_4) / 4;
		return score;
	}

	// ad aw ct 为0表示否，为1表示真
	public double peitaoindex_calculator(Integer ad, Integer aw, Integer ct, Integer river_type) {
		double score = 0;
		List<double[]> indexValue = getIndexValue("peitaoIndex", String.valueOf(river_type));
		double[] gradeTable = indexValue.get(0);
		score = gradeTable[0];
		if (river_type == 1) {
			if (ad == 0) {
				score = score - 2;
			}
			if (aw == 0) {
				score = score - 1;
			}
			if (ct == 0) {
				score = score - 1;
			}
		}
		else if (river_type == 4) {
			if (ad == 0) {
				score = score - 2;
			}
			if (aw == 0) {
				score = score - 2;
			}
			if (ct == 0) {
				score = score - 1;
			}
		}
		else if (river_type == 2 || river_type == 5 || river_type == 6 || river_type == 7) {
			if (ad == 0) {
				score = score - 2;
			}
			if (aw == 0) {
				score = score - 2;
			}
			if (ct == 0) {
				score = score - 2;
			}
		}
		if (score < 0) {
			score = 0;
		}
		return score;
	}

	public double guangaiindex_calculator(Integer nn, Integer db, Integer river_type) {
		double score = 0;
		List<double[]> indexValue = getIndexValue("guangaiIndex", String.valueOf(river_type));
		double[] gradeTable = indexValue.get(0);
		score = gradeTable[0];
		score = score - 2 * nn - db;
		if (score < 0) {
			score = 0;
		}
		return score;
	}

	public double shuimianindex_calculator(Integer xj, Integer dj, Double td, Integer river_type) {
		double score = 0;
		List<double[]> indexValue = getIndexValue("shuimianIndex", String.valueOf(river_type));
		double[] gradeTable = indexValue.get(0);
		score = gradeTable[0];
		score = score - xj - 2 * dj;
		if (river_type == 2) {
			if (td < 40) {
				score = score - (40 - td) * 4 / 40;
			}
		}
		else if (river_type == 1 || river_type == 3) {
			if (td < 30) {
				score = score - (30 - td) * 4 / 30;
			}
		}
		else {
			if (td < 50) {
				score = score - (50 - td) * 2 / 50;
			}
		}
		if (score < 0) {
			score = 0;
		}
		return score;
	}

	public double andaiindex_calculator(Double ap, Double as, Integer river_type) {
		if (as == 0) {
			return 0;
		}
		List<double[]> indexValue = getIndexValue("andaiIndex", "scoreIntervals", String.valueOf(river_type));

		double[] scoreIntervals = indexValue.get(0);
		double[] gradeTable = indexValue.get(1);
		double zhibei_rate = ap / as * 100.0;
		return calculateScore(zhibei_rate, scoreIntervals, gradeTable);
	}

	public double shuizhiindex_calculator(Integer st, Integer river_type) {
		double score = 0;
		List<double[]> indexValue = getIndexValue("shuizhiIndex", String.valueOf(river_type));
		double[] gradeTable = indexValue.get(0);
		if (st == 0 || st == 1 || st == 2) {
			score = gradeTable[0];
		}
		else {
			score = gradeTable[st - 2];
		}
		return score;
	}

	public double qupaiindex_calculator(Integer nq, Integer np, Integer nsz, Integer river_type) {
		double score = 0;
		List<double[]> indexValue = getIndexValue("qupaiIndex", String.valueOf(river_type));
		double[] gradeTable = indexValue.get(0);
		score = gradeTable[0] - nq - np - nsz;
		if (score < 0) {
			score = 0;
		}
		return score;
	}

	public double ruheindex_calculator(Integer nw, Integer river_type) {
		double score = 0;
		List<double[]> indexValue = getIndexValue("ruheIndex", String.valueOf(river_type));
		double[] gradeTable = indexValue.get(0);
		score = gradeTable[0];
		if (river_type == 2) {
			score = score - 2 * nw;
		}
		else if (river_type == 3) {
			score = score - nw;
		}
		if (score < 0) {
			score = 0;
		}
		return score;
	}

	// ns表示四乱个数，nh=1表示未划定管理范围，nj=1表示未设置界桩，ng=1表示未编制规划，ni=1表示未建设信息化系统
	public double kongjianindex_calculator(Integer ns, Integer nh, Integer nj, Integer ng, Integer ni,
			Integer river_type) {
		double score = 0;
		List<double[]> indexValue = getIndexValue("kongjianIndex", String.valueOf(river_type));
		double[] gradeTable = indexValue.get(0);
		score = gradeTable[0];
		score = score - ns - nh - nj - ng - ni;
		if (score < 0) {
			score = 0;
		}
		return score;
	}

	// 水位流量这里分值有简化，汛期和旱期采用了一样的区间和分值
	public double liuliangindex_calculator(Double hl, Double xl, Integer river_type) {
		double score = 0;
		List<double[]> indexValue = getIndexValue("liuliangIndex", "scoreIntervals", String.valueOf(river_type));
		double[] scoreIntervals = indexValue.get(0);
		double[] gradeTable = indexValue.get(1);
		score = (calculateScore(hl, scoreIntervals, gradeTable) + calculateScore(xl, scoreIntervals, gradeTable)) / 2;
		return score;
	}

	// 湖水流连通性中的公式？？
	public double shuiliuindex_calculator(Integer dn, Integer yhn, Integer river_type) {
		double score = 0;
		List<double[]> indexValue = getIndexValue("shuiliuIndex", String.valueOf(river_type));
		double[] gradeTable = indexValue.get(0);
		score = gradeTable[0] - 2 * dn - yhn;
		if (score < 0) {
			score = 0;
		}
		return score;
	}

	public double fuyouindex_calculator(Double fd, Integer river_type) {
		double score = 0;
		List<double[]> indexValue = getIndexValue("fuyouIndex", "scoreIntervals", String.valueOf(river_type));
		double[] scoreIntervals = indexValue.get(0);
		double[] gradeTable = indexValue.get(1);
		return calculateScore(fd, scoreIntervals, gradeTable);
	}

	public double yuleiindex_calculator(Integer xyn, Integer syn, Integer river_type) {
		if (syn == 0) {
			return 0;
		}
		List<double[]> indexValue = getIndexValue("yuleiIndex", "scoreIntervals", String.valueOf(river_type));
		double[] scoreIntervals = indexValue.get(0);
		double[] gradeTable = indexValue.get(1);
		double yulei_rate = xyn.doubleValue() / syn * 100;
		return calculateScore(yulei_rate, scoreIntervals, gradeTable);
	}

	public double shuiniaoindex_calculator(Integer sz, Integer river_type) {
		double score = 0;
		List<double[]> indexValue = getIndexValue("shuiniaoIndex", String.valueOf(river_type));
		double[] gradeTable = indexValue.get(0);
		score = gradeTable[sz]; // sz为0、1、2，0为最好。
		return score;
	}

	public double diqiindex_calculator(Double dd, Integer river_type) {
		double score = 0;
		List<double[]> indexValue = getIndexValue("diqiIndex", "scoreIntervals", String.valueOf(river_type));
		double[] scoreIntervals = indexValue.get(0);
		double[] gradeTable = indexValue.get(1);
		return calculateScore(dd, scoreIntervals, gradeTable);
	}

	public double shengtaiindex_calculator(Double dn, Double yhn, Integer river_type) {
		double score = 0;
		List<double[]> indexValue = getIndexValue("shengtaiIndex", "scoreIntervals", String.valueOf(river_type));
		double[] scoreIntervals = indexValue.get(0);
		double[] gradeTable = indexValue.get(1);
		return calculateScore(dn < yhn ? dn : yhn, scoreIntervals, gradeTable);
	}

	public double shuishengindex_calculator(Integer yh, Integer river_type) {
		double score = 0;
		List<double[]> indexValue = getIndexValue("shuishengIndex", String.valueOf(river_type));
		double[] gradeTable = indexValue.get(0);
		score = gradeTable[0] - yh;
		if (score < 0) {
			score = 0;
		}
		return score;
	}

	public double wenhuaindex_calculator(Integer zc, Integer river_type) {
		double score = 0;
		List<double[]> indexValue = getIndexValue("wenhuaIndex", String.valueOf(river_type));
		double[] gradeTable = indexValue.get(0);
		score = gradeTable[zc]; // zc为0、1、2、3，0为最好。
		return score;
	}

	public double yicunindex_calculator(Integer syb, Integer rtn, Integer river_type) {
		List<double[]> indexValue = getIndexValue("yicunIndex", "scoreIntervals", String.valueOf(river_type));
		double[] scoreIntervals = indexValue.get(0);
		double[] gradeTable = indexValue.get(1);
		return calculateScore((syb.doubleValue() * 100) / rtn, scoreIntervals, gradeTable);
	}

	public double jingguanindex_calculator(Integer gs, Integer qb, Integer river_type) {
		double score = 0;
		double score_1 = 0;
		double score_2 = 0;
		List<double[]> indexValue = getIndexValue("jingguanIndex", String.valueOf(river_type));
		double[] gradeTable = indexValue.get(0);
		score_1 = gradeTable[gs]; // gs为0、1、2、3、4，0为最好
		score_2 = gradeTable[qb]; // qb为0、1、2、3、4，0为最好
		score = (score_1 + score_2) / 2;
		return score;
	}

	public double teseindex_calculator(Integer tzg, Integer river_type) {
		double score = 0;
		List<double[]> indexValue = getIndexValue("teseIndex", String.valueOf(river_type));
		double[] gradeTable = indexValue.get(0);
		score = gradeTable[tzg]; // tzg为0、1、2，0为最好
		return score;
	}

	public double manyiindex_calculator(Double myc, Integer river_type) {
		List<double[]> indexValue = getIndexValue("manyiIndex", "scoreIntervals", String.valueOf(river_type));
		double[] scoreIntervals = indexValue.get(0);
		double[] gradeTable = indexValue.get(1);
		return calculateScore(myc, scoreIntervals, gradeTable);
	}

	public int findIndex(double input, double[] array) {
		int index = 0;
		for (double num : array) {
			if (num > input) {
				index++;
			}
		}
		return index;
	}

	// 计算区间内差值
	public double calculate_interval_rate(double num, double left, double right) {
		if (left - right == 0) {
			return 1.0;
		}
		else {
			return (num - right) / (left - right);
		}
	}

	// 获得区间
	public double[] get_interval(int index, double[] array) {
		int len = array.length;
		double left = 100, right = 100;
		if (index == 0) {
			left = 100;
			right = array[index];
		}
		else if (index == len) {
			right = 0;
			left = array[index - 1];
		}
		else {
			left = array[index - 1];
			right = array[index];
		}
		return new double[] { left, right };
	}

	public double calculateScore(double input, double[] scoreIntervals, double[] gradeTable) {
		int index = findIndex(input, scoreIntervals);
		double score = 0;
		double base_score = 0;
		double top_score = 0;
		System.out.println("############### Calculating  ############### \n");
		double[] result = get_interval(index, scoreIntervals);

		double left = result[0];
		double right = result[1];
		System.out.println("[" + left + "," + right + "]");
		System.out.println("Index is:" + index);
		double rate = calculate_interval_rate(input, left, right);

		// 不用计算，满分
		if (index == 0) {
			score = gradeTable[0];
		}
		else if (index == gradeTable.length) {
			base_score = 0;
			top_score = gradeTable[gradeTable.length - 1];
			score = top_score - (1.00 - rate) * (top_score - base_score);
		}
		else {
			base_score = gradeTable[index];
			top_score = gradeTable[index - 1];
			score = top_score - (1.00 - rate) * (top_score - base_score);
		}

		System.out.println("topScore is:" + top_score);
		System.out.println("baseScore is:" + base_score);
		System.out.println("rate is:" + rate);
		System.out.println("Score is:" + score);
		System.out.println("############### Completed  ############### \n");
		return score;

	}

	public int findIndex_1(double input, double[] array) {
		int index = 0;
		for (double num : array) {
			if (num < input) {
				index++;
			}
		}
		return index;
	}

	// 计算区间内差值
	public double calculate_interval_rate_1(double num, double left, double right) {
		if (right - left == 0) {
			return 1.0;
		}
		else {
			return (right - num) / (right - left);
		}
	}

	// 获得区间
	public double[] get_interval_1(int index, double[] array) {
		int len = array.length;
		double left = 0, right = 0;
		if (index == 0) {
			left = 0;
			right = array[index];
		}
		else if (index == len) {
			right = array[index - 1];
			left = array[index - 1];
		}
		else {
			left = array[index - 1];
			right = array[index];
		}
		return new double[] { left, right };
	}

	public double calculateScore_1(double input, double[] scoreIntervals, double[] gradeTable) {
		int index = findIndex_1(input, scoreIntervals);
		double score = 0;
		double base_score = 0;
		double top_score = 0;
		System.out.println("############### Calculating  ############### \n");
		double[] result = get_interval_1(index, scoreIntervals);

		double left = result[0];
		double right = result[1];
		System.out.println("[" + left + "," + right + "]");
		System.out.println("Index is:" + index);
		double rate = calculate_interval_rate_1(input, left, right);

		// 不用计算，满分
		if (index == 0) {
			score = gradeTable[0];
		}
		else if (index == gradeTable.length) {
			base_score = 0;
			top_score = gradeTable[gradeTable.length - 1];
			score = top_score - (1.00 - rate) * (top_score - base_score);
		}
		else {
			base_score = gradeTable[index];
			top_score = gradeTable[index - 1];
			score = top_score - (1.00 - rate) * (top_score - base_score);
		}

		System.out.println("topScore is:" + top_score);
		System.out.println("baseScore is:" + base_score);
		System.out.println("rate is:" + rate);
		System.out.println("Score is:" + score);
		System.out.println("############### Completed  ############### \n");
		return score;
	}

	public double tiaoxuindex_calculator(Double x, Double s, Integer river_type) {
		if (s == 0) {
			return 0;
		}
		List<double[]> indexValue = getIndexValue("tiaoxuIndex", "scoreIntervals", String.valueOf(river_type));
		double[] scoreIntervals = indexValue.get(0);
		double[] gradeTable = indexValue.get(1);
		double tiaoxu_rate = x / s * 100;
		return calculateScore(tiaoxu_rate, scoreIntervals, gradeTable);
	}

	public double ruhuindex_calculator(Integer dbh, Integer tn, Integer river_type) {
		if (tn == 0) {
			return 0;
		}
		List<double[]> indexValue = getIndexValue("ruhuIndex", "scoreIntervals", String.valueOf(river_type));
		double[] scoreIntervals = indexValue.get(0);
		double[] gradeTable = indexValue.get(1);
		double ruhu_rate = dbh.doubleValue() / tn * 100.0;
		return calculateScore(ruhu_rate, scoreIntervals, gradeTable);
	}

	public double shuiweiindex_calculator(Integer smz, Integer river_type) {
		List<double[]> indexValue = getIndexValue("shuiweiIndex", String.valueOf(river_type));
		double[] gradeTable = indexValue.get(0);
		double score;
		score = gradeTable[smz]; // smz为0、1、2、3、4，0为最好
		return score;
	}

	public double shuiliu1index_calculator(Integer zg, Double lb, Integer river_type) {
		double score = 0;
		double score_1 = 0;
		double score_2 = 0;
		List<double[]> indexValue = getIndexValue("shuiliu1Index", "scoreIntervals", String.valueOf(river_type));
		double[] scoreIntervals = indexValue.get(0);
		double[] gradeTable = indexValue.get(1);
		score_1 = gradeTable[zg]; // zg为0（0月），1（1月），2（2月），3（4月），4（12月），0最好
		score_2 = calculateScore(lb, scoreIntervals, gradeTable);
		score = (score_1 + score_2) / 2;
		return score;
	}

	// taihu为1是太湖，为0为其他
	public double shuitiindex_calculator(Double lm, Integer isTaihu, Integer river_type) {
		if (isTaihu == 1) {
			List<double[]> indexValue = getIndexValue("shuitiIndex", "scoreIntervals_taihu", "taihu");
			double[] scoreIntervals = indexValue.get(0);
			double[] gradeTable = indexValue.get(1);
			return calculateScore_1(lm, scoreIntervals, gradeTable);
		}
		else {
			List<double[]> indexValue = getIndexValue("shuitiIndex", "scoreIntervals_qita", String.valueOf(river_type));
			double[] scoreIntervals = indexValue.get(0);
			double[] gradeTable = indexValue.get(1);
			return calculateScore_1(lm, scoreIntervals, gradeTable);
		}
	}

	public double fuyingindex_calculator(Double yzz, Integer river_type) {
		List<double[]> indexValue = getIndexValue("fuyingIndex", "scoreIntervals", String.valueOf(river_type));
		double[] scoreIntervals = indexValue.get(0);
		double[] gradeTable = indexValue.get(1);
		return calculateScore_1(yzz, scoreIntervals, gradeTable);
	}

}
